<?php
namespace Library;
/**
 * 通过获取静态方法查找当前所要验证的数据字段，通过‘;’分割每个字段所要验证的段，第一段为是否必须验证，第二段以后到最后一段为正则验证规则。若是最后一段包含‘->’表示为默认值，可使用PHP部分简单内置函数。
 * 
 */
use Library\Helper;
use Phalcon\Mvc\User\Plugin;
class GetRequest extends Plugin
{
    use Helper;

    private static  $my;
    
    private static function getself(){
        if(is_a(self::$my, 'GetRequest')){
            return self::$my;
        }
        self::$my=new self();
        return self::$my;
    }
    /**
     * 获取验证字段，返回验证通过的数据
     * 通过静态方式获取到要验证的字段，并用‘;’分割传递给filterRequest进行数据验证，最后将要获取的数据与验证通过的数据对比，返回要获取的字段
     * @param unknown $name 获取验证字段的关键字
     * @param array $param 要获取的数据，为空的话，默认获取全部的数据
     */
    public static  function __callstatic($name,$param=[]){
        $request=StateCode::getConfig('request');
        $b=self::getself();
        $postData=$b->post();
        //未传递要获取的数据，则默认为$_REQUEST的数据
        if(!$param){
            $param[0]=array_keys($postData);
        }
        if(!is_array($param[0]) || !isset($request->$name)){
            $b->e(StateCode::_30003());
        }

        $data=$request->$name->toArray();    
        
        foreach($data as $key=>$val){ 
            if(!in_array($key,$param[0]) && $param[0]){
                unset($data[$key]);
                continue;
            }
            $temp=explode(';', $val);
            
            $b->filterRequest($key,$temp,$postData);
        }
        //对比所要获取的数据，并返回
        $newData=array_intersect_key($postData, $data);
        return $newData;
    }
    
    /**
     * 规则验证
     * 循环验证，首先判断是否有‘=>’相似的数据，此符号表示某字段必须等于某字段，然后在验证是否为必填。当为必填的时候直接正则验证，不通过则退出。当不为必填时，则验证客户端是否传递此字段
     * 当客户端传递此字段，验证不通过时或者客户端未传递此字段时，则为此字段设定默认值。
     * @param string $key 验证的KEY
     * @param array $data 验证规则
     * @param array $postData 要处理的数据
     */
    private function filterRequest($key='',array $data,&$postData){
        //转换验证规则是否为必须,$data[0]值为字符串“true” or "false"
        eval('$data[0]= '.$data[0].';');
        //为必填时,不填写验证失败
        if($data[0] ===true && !isset($postData[$key])){
            $this->e(StateCode::_30003());
        }
       for($i =1;$i<count($data);$i++){
           //用于验证两个字段是否相等
           if($index=strpos($data[$i],'=>') !==false){
               $k=substr($data[$i],$index+1);
               if($postData[$key] !== $postData[$k]){
                   $this->e(StateCode::_30003());
               }
               continue;
           }
           $chart=$data[0]===false?strpos($data[$i],'->'):false;
           //当规则不为必填时并且客户端未传递此字段时，或客户端传递了此字段时进行验证失败时
           if((!isset($postData[$key]) && $data[0]===false) || $b=!preg_match($data[$i], trim($postData[$key]))){
               if($data[0] ===true){
                   $this->e(StateCode::_30003());
               }
               //设定了默认值时并且规则设定为不必填时验证失败或者客户端未传递该字段时进行默认值赋值
               if((!isset($postData[$key]) || $b) && $chart !==false){
                   $k=substr($data[$i],$chart+2);
                   $fn='$postData["'.$key.'"] = '.$k.';';
                   eval($fn);    
               }
           }
       }
       
    }
    
    /**
     * 不经验证，直接获取指定的数据
     * @param string $param
     */
    public static function getParam($param=''){
        if(is_string($param)){
            $param=explode(',', $param);
        }
        $temp=[];
        $post=self::getself()->post();
        foreach ($param as $val){
            if(isset($post[$val])){
                $temp[$val]=$post[$val];
            }else{
                $temp[$val]='';
            }
        }
        return $temp;
    }
}

?>